"""
pytest配置文件
设置测试夹具和钩子函数
"""
import pytest
import os
from datetime import datetime
from utils.webdriver_manager import WebDriverManager
from utils.logger import Logger
from config.test_config import TestConfig


@pytest.fixture(scope="session")
def logger():
    """全局日志记录器"""
    return Logger().get_logger()


@pytest.fixture(scope="function")
def driver(request):
    """
    WebDriver夹具
    为每个测试函数提供浏览器驱动
    """
    webdriver_manager = WebDriverManager()
    driver = None
    
    try:
        # 获取浏览器类型（从标记中获取）
        browser = TestConfig.BROWSER
        if hasattr(request, 'param'):
            browser = request.param
        
        # 创建浏览器驱动
        driver = webdriver_manager.get_driver(browser)
        
        # 设置测试名称
        test_name = request.function.__name__
        Logger().log_test_start(test_name)
        
        yield driver
        
    except Exception as e:
        Logger().log_error(f"创建浏览器驱动失败: {str(e)}")
        raise
    
    finally:
        # 测试结束后截图（如果失败）
        if driver and request.node.rep_call.failed:
            try:
                screenshot_path = webdriver_manager.take_screenshot(
                    f"failed_{request.function.__name__}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.png"
                )
                if screenshot_path:
                    # 将截图路径添加到测试报告中
                    request.node.screenshot_path = screenshot_path
            except Exception as e:
                Logger().log_error(f"截图失败: {str(e)}")
        
        # 关闭浏览器驱动
        if driver:
            webdriver_manager.quit_driver()
        
        # 记录测试结束
        if hasattr(request, 'function'):
            test_name = request.function.__name__
            status = "FAIL" if request.node.rep_call.failed else "PASS"
            Logger().log_test_end(test_name, status)


@pytest.fixture(scope="function")
def chrome_driver(driver):
    """Chrome浏览器驱动夹具"""
    return driver


@pytest.fixture(scope="function")
def firefox_driver(driver):
    """Firefox浏览器驱动夹具"""
    return driver


@pytest.fixture(scope="function")
def edge_driver(driver):
    """Edge浏览器驱动夹具"""
    return driver


@pytest.fixture(scope="session")
def test_data_dir():
    """测试数据目录夹具"""
    return TestConfig.TEST_DATA_DIR


@pytest.fixture(scope="session")
def report_dir():
    """测试报告目录夹具"""
    return TestConfig.REPORT_DIR


# pytest钩子函数
def pytest_configure(config):
    """pytest配置钩子"""
    # 确保必要的目录存在
    os.makedirs(TestConfig.LOG_DIR, exist_ok=True)
    os.makedirs(TestConfig.REPORT_DIR, exist_ok=True)
    os.makedirs(TestConfig.SCREENSHOT_DIR, exist_ok=True)
    os.makedirs(TestConfig.TEST_DATA_DIR, exist_ok=True)


def pytest_runtest_setup(item):
    """测试运行前设置"""
    # 记录测试开始
    test_name = item.name
    Logger().log_test_start(test_name)


def pytest_runtest_teardown(item, nextitem):
    """测试运行后清理"""
    # 记录测试结束
    test_name = item.name
    Logger().log_test_end(test_name)


def pytest_runtest_makereport(item, call):
    """生成测试报告"""
    if call.when == "call":
        # 标记测试结果
        item.rep_call = call
        
        # 如果测试失败，记录详细信息
        if call.excinfo:
            Logger().log_error(f"测试失败: {item.name}", call.excinfo.value)


def pytest_collection_modifyitems(config, items):
    """修改测试收集项"""
    # 为所有测试添加默认标记
    for item in items:
        if not any(item.iter_markers()):
            item.add_marker(pytest.mark.ui)


def pytest_terminal_summary(terminalreporter, exitstatus, config):
    """终端总结"""
    # 输出测试统计信息
    passed = len(terminalreporter.stats.get('passed', []))
    failed = len(terminalreporter.stats.get('failed', []))
    skipped = len(terminalreporter.stats.get('skipped', []))
    
    Logger().log_info(f"测试总结: 通过={passed}, 失败={failed}, 跳过={skipped}")
    
    # 输出失败测试的截图路径
    for report in terminalreporter.stats.get('failed', []):
        if hasattr(report, 'screenshot_path'):
            Logger().log_info(f"失败测试截图: {report.screenshot_path}")


# 参数化浏览器类型
def pytest_generate_tests(metafunc):
    """生成参数化测试"""
    if "driver" in metafunc.fixturenames:
        # 根据标记选择浏览器
        if metafunc.config.getoption("--browser"):
            browser = metafunc.config.getoption("--browser")
            metafunc.parametrize("driver", [browser], indirect=True)
        else:
            # 默认使用配置的浏览器
            metafunc.parametrize("driver", [TestConfig.BROWSER], indirect=True)


# 自定义命令行选项
def pytest_addoption(parser):
    """添加自定义命令行选项"""
    parser.addoption(
        "--browser",
        action="store",
        default=TestConfig.BROWSER,
        help="指定浏览器类型 (chrome, firefox, edge)"
    )
    
    parser.addoption(
        "--headless",
        action="store_true",
        default=TestConfig.HEADLESS,
        help="无头模式运行"
    )
    
    parser.addoption(
        "--slow",
        action="store_true",
        help="运行慢速测试"
    ) 